/*
 * @Author: 李无敌
 * @Date: 2025-08-06 08:25:21
 * @LastEditors: 李无敌
 * @LastEditTime: 2025-08-12 15:36:17
 * @FilePath: \nest-base\src\modules\file\controllers\file.controller.ts
 */
import {
  Controller,
  Get,
  Post,
  Delete,
  Param,
  Query,
  Body,
  Res,
  StreamableFile,
  HttpStatus,
  HttpException,
  Req,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiConsumes, ApiParam, ApiQuery, ApiBearerAuth, ApiBody } from '@nestjs/swagger';
import { FastifyReply, FastifyRequest } from 'fastify';
import { createReadStream } from 'fs';
import { ConfigService } from '@nestjs/config';
import { FileService } from '../services/file.service';
import { CreateFileDto } from '../dto/create-file.dto';
import { UpdateFileDto } from '../dto/update-file.dto';
import { QueryFileDto } from '../dto/query-file.dto';
import { User } from '../../user/entities/user.entity';
import { CurrentUser } from '../../../common/decorators/current-user.decorator';
import { FastifyFile } from '../../../common/types/file.types';
import { Public } from '../../../common/decorators/roles.decorator';
import { ApiName } from '../../../common/decorators/api-name.decorator';
import { ApiResponseDto } from '../../../common/dto/response.dto';

@ApiTags('文件管理')
@ApiBearerAuth()
@Controller('file')
export class FileController {
  constructor(
    private readonly fileService: FileService,
    private readonly configService: ConfigService,
  ) {}

  @ApiOperation({ summary: '上传文件' })
  @ApiName('文件上传')
  @ApiResponse({ status: 200, description: '文件上传成功' })
  @ApiResponse({ status: 400, description: '请求参数错误' })
  @ApiConsumes('multipart/form-data')
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        file: {
          type: 'string',
          format: 'binary',
          description: '要上传的文件',
        },
        description: {
          type: 'string',
          description: '文件描述',
        },
        tags: {
          type: 'string',
          description: '文件标签',
        },
        isPublic: {
          type: 'boolean',
          description: '是否公开访问',
          default: false,
        },
      },
    },
  })
  @Post('upload')
  async upload(
    @Req() req: FastifyRequest,
    @CurrentUser() user: any,
  ) {
    try {
      // 使用Fastify的方式获取上传的文件
      const file = await req.file();
      const fileBuffer = await file.toBuffer();
      
      // 从表单字段中获取其他数据
      const body = req.body as any;
      const description = body?.description;
      const tags = body?.tags;
      const isPublic = body?.isPublic === 'true' || body?.isPublic === true;
      
      // 创建一个类似Multer的文件对象
      const multerFile: FastifyFile = {
        buffer: fileBuffer,
        originalname: file.filename,
        mimetype: file.mimetype,
        size: file.file.bytesRead,
        fieldname: file.fieldname,
      };
      
      // 创建文件DTO对象
      const createFileDto: CreateFileDto = {
        description,
        tags,
        isPublic,
      };
      
      const result = await this.fileService.upload(multerFile, createFileDto, user);
      return ApiResponseDto.success(result, '文件上传成功');
    } catch (error) {
      throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
    }
  }

  @ApiOperation({ summary: '下载文件' })
  @ApiName('文件下载')
  @ApiResponse({ status: 200, description: '文件下载成功' })
  @ApiResponse({ status: 404, description: '文件不存在' })
  @ApiParam({ name: 'id', description: '文件ID' })
  @Get('download/:id')
  async download(@Param('id') id: string, @Res({ passthrough: true }) res: FastifyReply) {
    try {
      const { filePath, originalName, mimeType } = await this.fileService.download(id);
      
      // 设置响应头
      res.header('Content-Type', mimeType);
      res.header('Content-Disposition', `attachment; filename="${encodeURIComponent(originalName)}"`);
      
      // 创建并返回文件流
      const file = createReadStream(filePath);
      return new StreamableFile(file);
    } catch (error) {
      throw new HttpException(error.message, HttpStatus.NOT_FOUND);
    }
  }

  // @ApiOperation({ summary: '获取文件信息' })
  // @ApiName('获取文件信息')
  // @ApiResponse({ status: 200, description: '获取成功' })
  // @ApiResponse({ status: 404, description: '文件不存在' })
  // @ApiParam({ name: 'id', description: '文件ID' })
  // @Get(':id')
  // async getFileInfo(@Param('id') id: string) {
  //   try {
  //     const result = await this.fileService.getFileInfo(id);
  //     return ApiResponseDto.success(result, '获取成功');
  //   } catch (error) {
  //     throw new HttpException(error.message, HttpStatus.NOT_FOUND);
  //   }
  // }

  @ApiOperation({ summary: '分页获取文件列表' })
  @ApiName('分页获取文件列表')
  @ApiResponse({ status: 200, description: '获取成功' })
  @Get("page")
  async getFileList(@Query() queryDto: QueryFileDto) {
    try {
      const result = await this.fileService.getFileList(queryDto);
      return ApiResponseDto.success(result, '获取成功');
    } catch (error) {
      throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
    }
  }

  // @Public()
  // @ApiOperation({ summary: '获取公开文件列表' })
  // @ApiName('获取公开文件列表')
  // @ApiResponse({ status: 200, description: '获取成功' })
  // @Get('public')
  // async getPublicFiles(@Query() queryDto: QueryFileDto) {
  //   try {
  //     const result = await this.fileService.getPublicFiles(queryDto);
  //     return ApiResponseDto.success(result, '获取成功');
  //   } catch (error) {
  //     throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
  //   }
  // }

  // @ApiOperation({ summary: '更新文件信息' })
  // @ApiName('更新文件信息')
  // @ApiResponse({ status: 200, description: '更新成功' })
  // @ApiResponse({ status: 400, description: '请求参数错误' })
  // @ApiResponse({ status: 403, description: '没有权限' })
  // @Post('update')
  // async updateFileInfo(
  //   @Body() updateFileDto: UpdateFileDto,
  //   @CurrentUser() user: any,
  // ) {
  //   try {
  //     const result = await this.fileService.updateFileInfo(updateFileDto.id, updateFileDto, user);
  //     return ApiResponseDto.success(result, '更新成功');
  //   } catch (error) {
  //     throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
  //   }
  // }

  @ApiOperation({ summary: '删除文件' })
  @ApiName('删除文件')
  @ApiResponse({ status: 200, description: '删除成功' })
  @ApiResponse({ status: 400, description: '请求参数错误' })
  @ApiResponse({ status: 403, description: '没有权限' })
  @ApiBody({
    schema: {
      type: 'object',
      properties: {
        id: {
          type: 'string',
          description: '文件ID',
        },
      },
      required: ['id'],
    },
  })
  @Post('delete')
  async deleteFile(@Body() body: { id: string }, @CurrentUser() user: any) {
    try {
      const result = await this.fileService.deleteFile(body.id, user);
      return ApiResponseDto.success(result, '删除成功');
    } catch (error) {
      throw new HttpException(error.message, HttpStatus.BAD_REQUEST);
    }
  }

}
